import 'dart:typed_data';

import 'package:bluetooth_protocols_plugin/src/tools/bit_field.dart';
import 'package:bluetooth_protocols_plugin/src/tools/bit_utils.dart';

import '../../../base/settings/settings_base.dart';
import '../../../tools/utils.dart';

/*
  typedef ARM_PACKED struct{
    uint32_t voice_packet_index;      //当前语音包号  范围 0~(0xFFFFFFFF-1)，0xFFFFFFFF表示当前没有语音包
    uint32_t RGB_packet_index;       //当前RGB灯包号        范围 0~(0xFFFFFFFF-1)，0xFFFFFFFF表示当前没有语音包
    uint16_t limit_speed;             //限速          单位0.01km/h  范围 0~8000
    uint16_t limit_speed_warning_level1; //限速          单位0.01km/h  范围 0~8000
    uint16_t limit_speed_warning_level2; //限速          单位0.01km/h  范围 0~8000
    int16_t pitch_zero;               //平衡角度零点  单位0.01°  范围 -1000~1000
    uint16_t stand_by_time;           //待机时间      单位 S  范围 0~64800(18h)  特别地 0 代表永不自动关机
    uint8_t driver_mode : 4;          //驱动模式      0 舒适模式 1 经典模式
    uint8_t ride_mode   : 4;          //骑行模式      0 普通模式 1 发烧者模式
    uint8_t sensation1;               //舒适模式软硬度  单位1%   范围 0~100
    uint8_t sensation2;               //经典模式软硬度  单位1%   范围 0~100
    uint8_t voice_volume;             //音量          单位1%   范围 0~100
    uint8_t rgb_light_mode;      //RGB灯模式   0 关闭   1使用音效文件   2 跟随音乐波动
    uint8_t low_threshold;            //照明灯开启的光照强度阈值 单位1%  范围 0~100
    uint8_t high_threshold;           //照明灯关闭的光照强度阈值 单位1%  范围 0~100
    uint8_t low_lamp_brightness;         //手动设置近光灯照明灯亮度     单位1%  范围 0~100
    uint8_t high_lamp_brightness;        //手动设置远光灯照明亮度     单位1%  范围 0~100
    uint8_t active_sound_sensitivity;   //主动声浪灵敏度       单位1%  范围 0~100
    uint16_t high_lamp_auto_switch_speed;//自动切换远近光的速度值阈值  单位0.01km/h  范围 0~8000
    int8_t speeding_feedback;         //加速反馈  单位 1%  范围 -100~100
    int8_t braking_feedback;          //刹车反馈  单位 1%  范围 -100~100
    uint16_t reserve[3];
    
    uint32_t audio_switch      : 1; //语音功能           0 关闭   1 开启
    uint32_t turn_signal_light : 1; //转向灯功能         0 关闭   1 开启
    uint32_t lift_up_detection : 1; //防飞转开关         0 关闭   1 开启
    uint32_t lamp_auto_switch  : 1; //照明灯自动开关     0 关闭   1 开启
    uint32_t auto_brightness   : 1; //照明灯自动亮度调节 0 关闭   1 开启
    uint32_t lock_mode         : 1; //锁车               0 关闭   1 开启
    uint32_t transport_mode    : 1; //运输模式           0 关闭   1 开启
    uint32_t load_detect       : 1; //负载检测           0 关闭   1 开启
    uint32_t no_load_detect    : 1; //空载检测           0 关闭   1 开启
    uint32_t low_battery_ride  : 1; //是否允许低电骑行   0 不允许 1 允许
    uint32_t active_sound      : 1; //主动声浪           0 关闭   1 开启
    uint32_t touch_key         : 1; //触摸快捷键         0 关闭   1 开启
    uint32_t usb_power_switch  : 1; //USB电源开关         0 关闭   1 开启
    uint32_t auto_close_screen : 1; //自动息屏开关         0 关闭   1 开启
    uint32_t range_estimate    : 1; //剩余里程估算       0 关闭   1 开启
    uint32_t assist_balance    : 1; //辅助平衡开关  0 关闭   1   开启
    uint32_t acce_feedback     : 1; //加减速反馈开关    0 关闭    1 开启
    uint32_t berm_angle_mode   : 1; //赛道倾角开关      0 关闭    1 开启
    uint32_t logo_light_status : 1; //logo灯开关                            0 关闭                 1 开启
    uint32_t reserve2          : 13; //保留

    (删除)TOUCH_KEY_DEFINE touch_key_define; //触摸快捷键功能定义
  }GNUC_PACKED VX_SETTING_INFO;
*/

// Lorin 设置信息
abstract class LorinSettings extends SettingsBase {
  int voicePacketIndex = 0; // 当前语音包号
  int rgbPacketIndex = 0; // 当前RGB灯包号
  int limitSpeed = 0; // 限速，单位 0.01km/h
  int limitSpeedWarningLevel1 = 0; // 限速警告级别1，单位 0.01km/h
  int limitSpeedWarningLevel2 = 0; // 限速警告级别2，单位 0.01km/h
  int pitchZero = 0; // 平衡角度零点，单位 0.01°
  int standByTime = 0; // 待机时间，单位 S
  int driverMode = 0; // 驱动模式
  int rideMode = 0; // 骑行模式
  int sensation1 = 0; // 舒适模式软硬度，单位 1%
  int sensation2 = 0; // 经典模式软硬度，单位 1%
  int voiceVolume = 0; // 音量，单位 1%
  int rgbLightMode = 0; // RGB灯模式
  int lowThreshold = 0; // 照明灯开启的光照强度阈值，单位 1%
  int highThreshold = 0; // 照明灯关闭的光照强度阈值，单位 1%
  int lowLampBrightness = 0; // 手动设置近光灯亮度，单位 1%
  int highLampBrightness = 0; // 手动设置远光灯亮度，单位 1%
  int activeSoundSensitivity = 0; // 主动声浪灵敏度，单位 1%
  int highLampAutoSwitchSpeed = 0; // 自动切换远近光的速度值阈值，单位 0.01km/h
  int speedingFeedback = 0; // 加速反馈，单位 1%
  int brakingFeedback = 0; // 刹车反馈，单位 1%
  List<int> reserve = [0, 0, 0]; // 保留字段
  bool audioSwitch = false; // 语音功能
  bool turnSignalLight = false; // 转向灯功能
  bool liftUpDetection = false; // 防飞转开关
  bool lampAutoSwitch = false; // 照明灯自动开关
  bool autoBrightness = false; // 照明灯自动亮度调节
  bool lockMode = false; // 锁车
  bool transportMode = false; // 运输模式
  bool loadDetect = false; // 负载检测
  bool noLoadDetect = false; // 空载检测
  bool lowBatteryRide = false; // 是否允许低电骑行
  bool activeSound = false; // 主动声浪
  bool touchKey = false; // 触摸快捷键
  bool usbPowerSwitch = false; // USB电源开关
  bool autoCloseScreen = false; // 自动息屏开关
  bool rangeEstimate = false; // 剩余里程估算
  bool assistBalance = false; // 辅助平衡开关
  bool acceFeedback = false; // 加减速反馈开关
  bool bermAngleMode = false; // 赛道倾角开关
  bool logoLightStatus = false; // logo灯开关
  int reserve2 = 0; // 保留字段

  LorinSettings.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
    if (bytes.length < minLength) {
      throw ArgumentError(
          '字节数组长度不足，无法解析 $runtimeType，期望长度至少为 $minLength，实际长度为 ${bytes.length}');
    }
    var byteData = ByteData.sublistView(bytes);
    voicePacketIndex = byteData.getUint32(0, Endian.little);
    rgbPacketIndex = byteData.getUint32(4, Endian.little);
    limitSpeed = byteData.getUint16(8, Endian.little);
    limitSpeedWarningLevel1 = byteData.getUint16(10, Endian.little);
    limitSpeedWarningLevel2 = byteData.getUint16(12, Endian.little);
    pitchZero = byteData.getInt16(14, Endian.little);
    standByTime = byteData.getUint16(16, Endian.little);
    driverMode = BitUtils.getLowBits(byteData.getUint8(18), 4); // 取低4位
    rideMode = BitUtils.getHighBits(byteData.getUint8(18), 4); // 取高4位
    sensation1 = byteData.getUint8(19);
    sensation2 = byteData.getUint8(20);
    voiceVolume = byteData.getUint8(21);
    rgbLightMode = byteData.getUint8(22);
    lowThreshold = byteData.getUint8(23);
    highThreshold = byteData.getUint8(24);
    lowLampBrightness = byteData.getUint8(25);
    highLampBrightness = byteData.getUint8(26);
    activeSoundSensitivity = byteData.getUint8(27);
    highLampAutoSwitchSpeed = byteData.getUint16(28, Endian.little);
    speedingFeedback = byteData.getInt8(30);
    brakingFeedback = byteData.getInt8(31);
    reserve = [
      byteData.getUint16(32, Endian.little),
      byteData.getUint16(34, Endian.little),
      byteData.getUint16(36, Endian.little),
    ];

    // 解析位字段
    int bitField = byteData.getUint32(38, Endian.little);
    BitField bit = BitField(bitField);
    audioSwitch = bit[0] == 1;
    turnSignalLight = bit[1] == 1;
    liftUpDetection = bit[2] == 1;
    lampAutoSwitch = bit[3] == 1;
    autoBrightness = bit[4] == 1;
    lockMode = bit[5] == 1;
    transportMode = bit[6] == 1;
    loadDetect = bit[7] == 1;
    noLoadDetect = bit[8] == 1;
    lowBatteryRide = bit[9] == 1;
    activeSound = bit[10] == 1;
    touchKey = bit[11] == 1;
    usbPowerSwitch = bit[12] == 1;
    autoCloseScreen = bit[13] == 1;
    rangeEstimate = bit[14] == 1;
    assistBalance = bit[15] == 1;
    acceFeedback = bit[16] == 1;
    bermAngleMode = bit[17] == 1;
    logoLightStatus = bit[18] == 1;
  }

  @override
  int dataIntValue() {
    return Utils.computeDataIntVal(toBytes());
  }

  @override
  int dataLength() {
    return toBytes().length;
  }

  @override
  int get minLength => 42;

  @override
  Uint8List toBytes() {
    int driverAndRideMode = 0;
    driverAndRideMode = BitUtils.setBits(driverAndRideMode, 0, 3, driverMode);
    driverAndRideMode = BitUtils.setBits(driverAndRideMode, 4, 7, rideMode);
    var byteData = ByteData(minLength)
      ..setUint32(0, voicePacketIndex, Endian.little)
      ..setUint32(4, rgbPacketIndex, Endian.little)
      ..setUint16(8, limitSpeed, Endian.little)
      ..setUint16(10, limitSpeedWarningLevel1, Endian.little)
      ..setUint16(12, limitSpeedWarningLevel2, Endian.little)
      ..setInt16(14, pitchZero, Endian.little)
      ..setUint16(16, standByTime, Endian.little)
      ..setUint8(18, BitUtils.setBits(driverAndRideMode, driverMode, 0, 4))
      ..setUint8(18, BitUtils.setBits(driverAndRideMode, rideMode, 4, 4))
      ..setUint8(19, sensation1)
      ..setUint8(20, sensation2)
      ..setUint8(21, voiceVolume)
      ..setUint8(22, rgbLightMode)
      ..setUint8(23, lowThreshold)
      ..setUint8(24, highThreshold)
      ..setUint8(25, lowLampBrightness)
      ..setUint8(26, highLampBrightness)
      ..setUint8(27, activeSoundSensitivity)
      ..setUint16(28, highLampAutoSwitchSpeed, Endian.little)
      ..setInt8(30, speedingFeedback)
      ..setInt8(31, brakingFeedback)
      ..setUint16(32, reserve[0], Endian.little)
      ..setUint16(34, reserve[1], Endian.little)
      ..setUint16(36, reserve[2], Endian.little)
      ..setUint32(
        38,
        BitUtils.setBit(0, audioSwitch) |
            BitUtils.setBit(1, turnSignalLight) |
            BitUtils.setBit(2, liftUpDetection) |
            BitUtils.setBit(3, lampAutoSwitch) |
            BitUtils.setBit(4, autoBrightness) |
            BitUtils.setBit(5, lockMode) |
            BitUtils.setBit(6, transportMode) |
            BitUtils.setBit(7, loadDetect) |
            BitUtils.setBit(8, noLoadDetect) |
            BitUtils.setBit(9, lowBatteryRide) |
            BitUtils.setBit(10, activeSound) |
            BitUtils.setBit(11, touchKey) |
            BitUtils.setBit(12, usbPowerSwitch) |
            BitUtils.setBit(13, autoCloseScreen) |
            BitUtils.setBit(14, rangeEstimate) |
            BitUtils.setBit(15, assistBalance) |
            BitUtils.setBit(16, acceFeedback) |
            BitUtils.setBit(17, bermAngleMode) |
            BitUtils.setBit(18, logoLightStatus),
      );
    return byteData.buffer.asUint8List();
  }

  @override
  Map<String, dynamic> toMap() {
    return {
      'voicePacketIndex': voicePacketIndex,
      'rgbPacketIndex': rgbPacketIndex,
      'limitSpeed': limitSpeed,
      'limitSpeedWarningLevel1': limitSpeedWarningLevel1,
      'limitSpeedWarningLevel2': limitSpeedWarningLevel2,
      'pitchZero': pitchZero,
      'standByTime': standByTime,
      'driverMode': driverMode,
      'rideMode': rideMode,
      'sensation1': sensation1,
      'sensation2': sensation2,
      'voiceVolume': voiceVolume,
      'rgbLightMode': rgbLightMode,
      'lowThreshold': lowThreshold,
      'highThreshold': highThreshold,
      'lowLampBrightness': lowLampBrightness,
      'highLampBrightness': highLampBrightness,
      'activeSoundSensitivity': activeSoundSensitivity,
      'highLampAutoSwitchSpeed': highLampAutoSwitchSpeed,
      'speedingFeedback': speedingFeedback,
      'brakingFeedback': brakingFeedback,
      'reserve': reserve,
      'audioSwitch': audioSwitch,
      'turnSignalLight': turnSignalLight,
      'liftUpDetection': liftUpDetection,
      'lampAutoSwitch': lampAutoSwitch,
      'autoBrightness': autoBrightness,
      'lockMode': lockMode,
      'transportMode': transportMode,
      'loadDetect': loadDetect,
      'noLoadDetect': noLoadDetect,
      'lowBatteryRide': lowBatteryRide,
      'activeSound': activeSound,
      'touchKey': touchKey,
      'usbPowerSwitch': usbPowerSwitch,
      'autoCloseScreen': autoCloseScreen,
      'rangeEstimate': rangeEstimate,
      'assistBalance': assistBalance,
      'acceFeedback': acceFeedback,
      'bermAngleMode': bermAngleMode,
      'logoLightStatus': logoLightStatus,
      'reserve2': reserve2,
    };
  }
}
